﻿using AlarmModule.Enums;
using AlarmModule.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AlarmModule.Utils {
    /// <summary>
    /// 报警引擎,将评判标准给报警引擎
    /// </summary>
    public class AlarmEngine {

        private readonly Dictionary<string, AlarmParameter> _parameters;

        private readonly Dictionary<string, DateTime> _alarmTimers = new();
        // 在AlarmEngine中添加防抖逻辑
        private readonly Dictionary<string, DateTime> _lastAlarmTime = new();

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="parameters">报警参数:算是报警评判标准</param>
        public AlarmEngine(Dictionary<string, AlarmParameter> parameters) {
            _parameters = parameters;
        }

        /// <summary>
        /// 检测报警水平
        /// </summary>
        /// <param name="tagName"></param>
        /// <param name="currentValue"></param>
        /// <returns></returns>
        public AlarmLevel CheckAlarm(string tagName, double currentValue) {
            if (!_parameters.TryGetValue(tagName, out var param))
                return AlarmLevel.Normal;

            param.Value = currentValue; // 更新当前值

            // 1. 高低限报警检测
            AlarmLevel level = AlarmLevel.Normal;//报警级别
            if (currentValue >= param.HighHighLimit) level = AlarmLevel.HighHigh;
            else if (currentValue >= param.HighLimit) level = AlarmLevel.High;
            else if (currentValue <= param.LowLowLimit) level = AlarmLevel.LowLow;
            else if (currentValue <= param.LowLimit) level = AlarmLevel.Low;

            // 2. 偏差报警检测
            double deviation = Math.Abs(currentValue - param.Setpoint);//偏差值
            if (deviation > param.MaxDeviation && level == AlarmLevel.Normal) {
                level = AlarmLevel.High; // 偏差超限视为重要报警
            }

            // 3. 滞环与延时处理
            if (level != AlarmLevel.Normal) {
                // 首次检测到报警启动计时器
                if (!_alarmTimers.ContainsKey(tagName)) {
                    _alarmTimers[tagName] = DateTime.Now.AddMilliseconds(param.TriggerDelayMs);
                }
                // 达到延时时间才触发
                else if (DateTime.Now >= _alarmTimers[tagName]) {
                    _alarmTimers.Remove(tagName);
                    return level;
                }
            } else {
                // 恢复正常时清除计时器
                _alarmTimers.Remove(tagName);
            }
            //​​防误报设计
            if (level != AlarmLevel.Normal) {
                // 报警风暴抑制：30秒内不重复触发
                if (_lastAlarmTime.TryGetValue(tagName, out var lastTime) && (DateTime.Now - lastTime).TotalSeconds < 30) {
                    return AlarmLevel.Normal;
                }
                _lastAlarmTime[tagName] = DateTime.Now;
            }

            return AlarmLevel.Normal;
        }
    }
}
